use lib "../BuildTool/";
use BuildTool;


use Test::More tests => 8;
use Test::Exception;
use Data::Dumper;
 
 BEGIN {

 	use_ok(ITS);
 }

my $buildParams = "buildParams.txt";
my @params, my $its_path, my $rel_inc, my $project_name, my $buildReport = "buildReport.txt";

subtest 'Test Case 4.1' => sub {
	plan tests => 1;
####################################################################################
#	
# Verifying that the build not fail when open work items exist for the baseline and the 
# the flag is enabled
#
####################################################################################
	my $params_ref = BuildTool->readParams($buildParams);
	my @params = @$params_ref;
	my $type = "baseline";
	$its_path = $params[0];
	$rel_inc = $params[3];
	$project_name = $params[4];
	my $base_open_wi_allw = "true";
 	lives_ok{ITS->accessITS($its_path, $project_name, $rel_inc,$type,$base_open_wi_allw,$buildReport)}, 'Verifying that the tool lives if there\'re open work item and the flag is enabled';
 	system("rm -rf buildReport.txt");
};

subtest 'Test Case 4.2' => sub {
	plan tests => 1;
####################################################################################
#	
# Verifying that the build fails when open work items exist for the baseline and the 
# the flag is not enabled
#
####################################################################################
	my $type = "baseline";
	my $base_open_wi_allw = "false";
 	dies_ok{ITS->accessITS($its_path, $project_name, $rel_inc,$type,$base_open_wi_allw,$buildReport)}, 'Verifying that the tool dies if there\'re open work item and the flag is not enabled';
 	system("rm -rf buildReport.txt");
};

subtest 'Test Case 4.3' => sub {
	plan tests => 6;
####################################################################################
#	
# Verifying work items for the baseline: closed work items and only open work items
#
####################################################################################
#-------------------------------------------------------------------------------
#There are only closed work items in the inc2
#-------------------------------------------------------------------------------
	my $type = "baseline";
	my $base_open_wi_allw = "true";
	$rel_inc = "inc2";
	#Check if the tool doesn't die when there are only closed open items, because it will check for open work items
	#and the polarion export will throw a Java Exception
 	lives_ok{ITS->accessITS($its_path, $project_name, $rel_inc,$type,$base_open_wi_allw,$buildReport)}, 'Verifying that the tool lives when there are only closed work items';
 	#Get the file revisions
	my $rev_list_ref = BuildTool->getRevisions($type); 
	my @rev_list = @$rev_list_ref;
	is($rev_list[0],"10453","Verifying that the tools gets the correct revision for a baseline");
 	system("rm -rf buildReport.txt");
#-------------------------------------------------------------------------------
# There are only open work items in the inc3 - this situation should not happen 
#because only open work items means that it is the first baseline. And the first 
# baseline doesn't come to this flow.
#-------------------------------------------------------------------------------
	my $type = "baseline";
	my $base_open_wi_allw = "true";
	$rel_inc = "inc3";
	#Check that the tool lives but doesn't get the open work items revisions
 	lives_ok{ITS->accessITS($its_path, $project_name, $rel_inc,$type,$base_open_wi_allw,$buildReport)}, 'Verifying that the tool lives when there are only closed work items';
 	#Get the file revisions
	my $rev_list_ref = BuildTool->getRevisions($type); 
	my @rev_list = @$rev_list_ref;
	is($rev_list[0],undef,"Verifying that the tools does not get the revision related to the open work item");
 	system("rm -rf buildReport.txt");
#-------------------------------------------------------------------------------
#There are open and closed work items in the inc1
#-------------------------------------------------------------------------------
	my $type = "baseline";
	my $base_open_wi_allw = "true";
	my $has_wrong_rev = "false";
	$rel_inc = "inc1";
	#Check if the tool gets only the revisions related to the closed work items
 	lives_ok{ITS->accessITS($its_path, $project_name, $rel_inc,$type,$base_open_wi_allw,$buildReport)}, 'Verifying that the tool lives when there are only closed work items';
 	#Get the file revisions
	my $rev_list_ref = BuildTool->getRevisions($type); 
	my @rev_list = @$rev_list_ref;
	#There are 1 open work item (PG-28) and 1 closed work item (PG-29) in the inc1
	#The revision 1027 is linked to the open work item but not with the
	#closed work item
	foreach(@rev_list){
		if ($_ eq "1027"){
			$has_wrong_rev = "true";
		}
	}
	is($has_wrong_rev,"false","Verifying that the tools does not get the revision related to the open work item");
 	system("rm -rf buildReport.txt");
};

subtest 'Test Case 4.4' => sub {
	plan tests => 2;
####################################################################################
#	
# Verifying work items and linked revisions for the cron
#
####################################################################################
#-------------------------------------------------------------------------------
#There are open and closed work items in the inc1
#-------------------------------------------------------------------------------
	my $type = "cron";
	my $base_open_wi_allw = "true";
	$rel_inc = "inc1";
	#The work items related to this increment is the PG-28 and PG-29. The revisions
	# 9949, 9950,10365,9956 are duplicated because they exist in both work items
	my @expected_revisions = ('9895','9910','9926','9949','9950','9956','10365','10427','9956','9950','9949','10365');
 	lives_ok{ITS->accessITS($its_path, $project_name, $rel_inc,$type,$base_open_wi_allw,$buildReport)}, 'Verifying that the tool lives when there are only closed work items';
 	#Get the file revisions
	my $rev_list_ref = BuildTool->getRevisions($type); 
	my @rev_list = @$rev_list_ref;
	my %seen;
	my $number_elem = 0;
	$seen{$_}++ for @rev_list;
	#Check if all elements in expected_revisions array exists in rev_list array
	for my $item (@expected_revisions) {
    	if ($seen{$item}) {
        	$number_elem++;
    	}
	}
	#If the number of elements in rev_list array is the same as matched elements, the arrays are equal
	is($number_elem,scalar(@rev_list),"Verifying that the tools gets the correct revisions for a cron");
 	system("rm -rf buildReport.txt");
 
};

subtest 'Test Case 4.5' => sub {
############################################################################################
#	
# Verifying that the build fails when there is no closed work items and the build type is
# a baseline
#
############################################################################################
	plan tests => 1;
	my $type = "baseline";
	my $base_open_wi_allw = "true";
	$rel_inc = "inc3";
	#Set polarion parameters
 	ITS->accessITS($its_path, $project_name, $rel_inc,$type,$base_open_wi_allw,$buildReport);
 	#Get the file revisions
	my $rev_list_ref = BuildTool->getRevisions($type); 
	my @rev_list = @$rev_list_ref;
	#Verify if the build fails when there's no closed work items
	dies_ok{noWorkItems($type, \@rev_list_ref)}, "Verifying if the build fails when there's no closed work items";
 	system("rm -rf buildReport.txt");
};

#Subroutine to verify if there's closed work items for a baseline
sub noWorkItems{
	my $type = $_[0];
	my $rev_list_ref = $_[1];
	my @rev_list = @$rev_list_ref;
	if ($type eq "baseline" && $rev_list[0] eq ""){
		die "There's no closed work items";
	}
}

subtest 'Test Case 4.6' => sub {
	plan tests => 4;
############################################################################################
#	
# Verifying file changes between the current and past revisions for a work item - Analyzing
# if the ITS list is correct
#
############################################################################################
#---------------------------------------------------------------------------
# First test with revision 9956, taht has added and modified files
#---------------------------------------------------------------------------
	my $revision = 9956;
	my $vcs_path = "http://cad-test/repo/crdm/device/firmware/tools/build_tool/trunk/";
	#Get the file->reivision/status reference to the hash
	my $build_file_rev_changes_ref = VCS->getFileList($revision,$vcs_path);
	#Expected file->revision/status hash
	my %expected_file_rev = (
	'http://cad-test/repo/crdm/device/firmware/tools/build_tool/trunk/quals/main_fw/code/useless_file.txt' => [$revision,'A'],
	'http://cad-test/repo/crdm/device/firmware/tools/build_tool/trunk/quals/main_fw/code/shared_app/all_var.c' => [$revision,'M'],
	'http://cad-test/repo/crdm/device/firmware/tools/build_tool/trunk/quals/main_fw/code/shared_app/fillcode.c'=> [$revision,'M']
	);
	
	#Check if there're no changes, so the hashes are equal
	is(checkHashesAreEqual(\%expected_file_rev,$build_file_rev_changes_ref),0,'Verifying that the files->revision/status are equal to expected - added and modified files');
#---------------------------------------------------------------------------
# Second test with revision 9910, that has a deleted file
#---------------------------------------------------------------------------
	my $revision = 9910;
	my $vcs_path = "http://cad-test/repo/crdm/device/firmware/tools/build_tool/trunk/";
	#Get the file->reivision/status reference to the hash
	my $build_file_rev_changes_ref = VCS->getFileList($revision,$vcs_path);
	#Expected file->revision/status hash
	my %expected_file_rev = (
	'http://cad-test/repo/crdm/device/firmware/tools/build_tool/trunk/quals/main_fw/code/baseInfo.txt' => [$revision,'D']
	);
	
	#Check if there're no changes, so the hashes are equal
	is(checkHashesAreEqual(\%expected_file_rev,$build_file_rev_changes_ref),0,'Verifying that the files->revision/status are equal to expected - deleted file');
#---------------------------------------------------------------------------------------
# Third test with the expected_file_rev different from the build_file_rev_changes
# to test the subroutine checkHahsesAreEqual - Same file and revision, different status
#---------------------------------------------------------------------------------------
	my $revision = 9910;
	my $vcs_path = "http://cad-test/repo/crdm/device/firmware/tools/build_tool/trunk/";
	#Get the file->reivision/status reference to the hash
	my $build_file_rev_changes_ref = VCS->getFileList($revision,$vcs_path);
	#Expected file->revision/status hash
	my %expected_file_rev = (
	'http://cad-test/repo/crdm/device/firmware/tools/build_tool/trunk/quals/main_fw/code/baseInfo.txt' => [$revision,'A']
	);
	#Check if there're no changes, so the hashes are equal
	is(checkHashesAreEqual(\%expected_file_rev,$build_file_rev_changes_ref),1,'Verifying that the files->revision/status are different');
#---------------------------------------------------------------------------------------
# Fourth test with the expected_file_rev different from the build_file_rev_changes
# to test the subroutine checkHahsesAreEqual - Different file
#---------------------------------------------------------------------------------------
	my $revision = 9910;
	my $vcs_path = "http://cad-test/repo/crdm/device/firmware/tools/build_tool/trunk/";
	#Get the file->reivision/status reference to the hash
	my $build_file_rev_changes_ref = VCS->getFileList($revision,$vcs_path);
	#Expected file->revision/status hash
	my %expected_file_rev = (
	'This file doesnt exist.txt' => [$revision,'A']
	);
	#Check if there're no changes, so the hashes are equal
	is(checkHashesAreEqual(\%expected_file_rev,$build_file_rev_changes_ref),1,'Verifying that the files->revision/status are different');
};

sub checkHashesAreEqual{
	my $expected_hash_ref = $_[0];
	my %expected_hash = %$expected_hash_ref;
	my $hash_ref = $_[1];
	my %hash = %$hash_ref;
	my $n_changes = 0;
	foreach ( keys %expected_hash) {
		#Check if the file exists
		if ( exists $hash{$_} ) {
			#Get the revision/status arrays
			my @build_rev_status = @{$hash{$_}};
			my @expected_rev_status = @{$expected_hash{$_}};
			#Check if the revision and status are equal
			if (($expected_rev_status[0] eq $build_rev_status[0]) && ($expected_rev_status[1] eq $build_rev_status[1])) {
			#Do nothing
			}
			else {
			#Increase the number of changes
				$n_changes++;
			}
		}
		else {
			#If the file doensn't exist, increase the number of changes
			$n_changes++;
		}
	}
return $n_changes;
}

subtest 'Test Case 4.7' => sub {
	plan tests => 1;
####################################################################################
#	
# Verifying build_file_rev_changes hash when a file has more than one revision
#
####################################################################################
	#Both 10451 and 10453 revisions modified the dummy_file.txt
	my @rev_list = (10451,10453);
	my $vcs_path = "http://cad-test/repo/crdm/device/firmware/tools/build_tool/trunk/";
	my $final_revision;
	#Get the file->reivision/status reference to the hash
	foreach (@rev_list) {
		$build_file_rev_changes_ref = VCS->getFileList($_,$vcs_path); 
		%build_file_rev_changes = %$build_file_rev_changes_ref;
	}
	if(exists $build_file_rev_changes{'http://cad-test/repo/crdm/device/firmware/tools/build_tool/trunk/quals/main_fw/code/dummy_file.txt'}) {
		my @rev_status = @{$build_file_rev_changes{'http://cad-test/repo/crdm/device/firmware/tools/build_tool/trunk/quals/main_fw/code/dummy_file.txt'}};
		$final_revision = $rev_status[0];	
	}
	is($final_revision,10453,"Verifying that the final revision is the greater one");
};





 